package gat.common.util;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.bitsun.core.common.auth.JwtUtils;
import com.bitsun.core.common.enums.UserTypeEnum;
import com.bitsun.core.common.exception.AppException;
import com.bitsun.core.common.util.JsonUtil;
import com.bitsun.core.common.web.CurrentUser;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;

/**
 * jwt工具类
 *
 * @author chenshun
 * @email sunlightcs@gmail.com
 * @date 2017/9/21 22:21
 */
@Data
@Slf4j
@Component
public class JwtUtil {

    private static final long expireTime = 15 * 24 * 60 * 60 * 1000;

    /**
     * 密钥
     */
    private static final String TOKEN_SECRET = "zhe_jiang_yun_dun";

    /**
     * 生成签名，一天后过期
     *
     * @param **username**
     * @param **password**
     * @return
     */
    public static String createToken(CurrentUser params) {
        try {
            // 设置过期时间
            Date date = new Date(System.currentTimeMillis() + expireTime);
            // 私钥和加密算法
            Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
            // 设置头部信息
            Map<String, Object> header = new HashMap<>(2);
            header.put("Type", "Jwt");
            header.put("alg", "HS256");
            // 返回token字符串
            return JWT.create()
                    .withHeader(header)
                    .withClaim("currentUser", JsonUtil.toJsonString(params))
                    .withExpiresAt(date)
                    .sign(algorithm);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    private static final long backGroundUserExpireTime = 4 * 3600000L;


    public static String backGroundUserCreateToken(CurrentUser params) {
        try {
            Date date = new Date(System.currentTimeMillis() + 4 * 3600000L);
            Algorithm algorithm = Algorithm.HMAC256("zhe_jiang_yun_dun");
            Map<String, Object> header = new HashMap(2);
            header.put("Type", "Jwt");
            header.put("alg", "HS256");
            return JWT.create().withHeader(header).withClaim("currentUser", JsonUtil.toJsonString(params)).withExpiresAt(date).sign(algorithm);
        } catch (Exception var4) {
            var4.printStackTrace();
            return null;
        }
    }


    /**
     * 检验token是否正确
     *
     * @param **token**
     * @return
     */
    public static String verifyToken(String token) {
        Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
        JWTVerifier verifier = JWT.require(algorithm).build();
        try {
            DecodedJWT jwt = verifier.verify(token);
            return jwt.getClaim("currentUser").asString();
        } catch (Exception e) {
            throw new AppException("登录信息已过期", "000001");
        }
    }


    public static String refreshToken(String token) {
        Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
        JWTVerifier verifier = JWT.require(algorithm).build();
        DecodedJWT jwt = verifier.verify(token);
        long expireTime = jwt.getExpiresAt().getTime() - System.currentTimeMillis();
        String currentUser = jwt.getClaim("currentUser").asString();
        CurrentUser user = JSON.parseObject(currentUser, CurrentUser.class);
        if (Objects.equals(user.getUserType(), UserTypeEnum.COMMON.getCode())){
            if (0 < expireTime && expireTime < (2 * 60 * 60 * 1000)) {
                return JwtUtil.createToken(user);
            }
        }else {
            if (0 < expireTime && expireTime < (180 * 60 * 1000)) {
                return JwtUtil.backGroundUserCreateToken(user);
            }
        }

        return null;
    }

    public static void main(String[] args) throws InterruptedException {
        CurrentUser currentUser = new CurrentUser();
//        currentUser.setMain(true);
//        currentUser.setChannelUser(false);
//        currentUser.setAuthingId("abc");
//        currentUser.setChannelCode("C123");
//        currentUser.setUserCode("sgdfjkhgsdjkfhsjkd");
//        currentUser.setTenantId("123");
        String token = createToken(currentUser);
        System.out.println("token == " + token);
        String result = verifyToken(token);
        Thread.sleep(30000);
        String token1 = verifyToken(token);
//        System.out.println("result == " + result);
    }
}
